package com.huitone.smspfm.interfacz.tasks;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;

import com.bin.common.utils.DateTimeUtils;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.interfacz.logger.ExtLogger;
import com.huitone.smspfm.interfacz.model.MtOldSms;
import com.huitone.smspfm.interfacz.model.SmsEntityForMt;
import com.huitone.smspfm.interfacz.model.SmsSpeedStatistics;
import com.huitone.smspfm.interfacz.core.AppStaticConfigs;
import com.huitone.smspfm.interfacz.core.contant.DealResult;
import com.huitone.smspfm.interfacz.core.filewriter.FileRoute;
import com.huitone.smspfm.redis.model.AppCanstant;
import com.huitone.smspfm.redis.pipeline.PipelineOpts.ABExcuteCommands;

/**   
* @Title SmsPlatformSwitchTask.java 
* @Package com.huitone.smspfm.interfacz.tasks 
* @Description 短信新旧平台切换后处理程序
* @author ouzaihui   
* @date 
* @version V1.0   
*/
public class SmsPlatformSwitchTask extends Thread {
	
	private static final ExtLogger logger = ExtLogger.create(SmsPlatformSwitchTask.class);	
	
	private boolean keepGoing = true;
	
	//间隔时间
	private int excuteIntevel = 1*1000;
	
	//线程执行时间
	private long destroyTime = 30*60;
	
	private long startTime = 0;
	
	
	private ExecutorService platformSwitchPool = new ThreadPoolExecutor(AppStaticConfigs.platformSwitchPoolSize, 
			AppStaticConfigs.platformSwitchPoolSize, 1L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(AppStaticConfigs.platformSwitchPoolSize * 2), new RejectedExecutionHandler() {
		
		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			boolean offer = false;
			while(!executor.isShutdown() && !offer) {
				offer = executor.getQueue().offer(r);
				if (!offer) {
					try {
						TimeUnit.MILLISECONDS.sleep(10);
					} catch (InterruptedException e) {}
				}
			}
		}
	});
	
	@Override
	public void run() {	
		startTime = System.currentTimeMillis();
		Date sdealTime = new Date();
		//程序运行于旧平台下
		if(! AppStaticConfigs.smsRuningFlag){
			
		
			while (!this.isInterrupted() && isKeepGoing() && AppStaticConfigs.smsRuningFlag) {
				switchOldSmsPlatform();
			}
			
			this.destroy();
		} else {
			// 旧平台切换至新平台
			//啥都不用做直接结束
			this.destroy();
		}
	}




	private void switchOldSmsPlatform() {
		//禁发短信处理
		platformSwitchPool.execute(new Runnable() {
			
			@Override
			public void run() {
				forbidHandle();
				
			}
		});
		
		
		// 优先级队列处理
		platformSwitchPool.execute(new Runnable() {
			
			@Override
			public void run() {
				riorityHandle(); 
			}
		});
		

		try {
			Thread.sleep(excuteIntevel);
		} catch (InterruptedException e) {
		}
		long endTime = System.currentTimeMillis();
		
		long time = (endTime - startTime)/1000;
		if(time > destroyTime){
			this.destroy();
		}
	}





	private void riorityHandle() {
		RedisScript<List> script = new DefaultRedisScript<List>(
				AppStaticConfigs.luaGetPriority, List.class);
		
		List<String> keys = new ArrayList<>();
		keys.add(AppStaticConfigs.isMPriorityList);
		keys.add(AppStaticConfigs.pSMCacheHash);
		
		List<List<String>> entities = AppStaticConfigs.scriptOpts3
				.getSMCacheAndHash(script, keys,
						AppStaticConfigs.mtfbdBatchSizePerTime+ "",
						AppStaticConfigs.smsSrvId);
		

		for (int i = 0; i < entities.size(); i++) {
			logger.info("读取到" + entities.size() + "该平台下的优先级队列短信");
			List<String> list = entities.get(i);
			MtOldSms smsEntity = MtOldSms
					.parse(list);
			// 写入文件中
			List<String> msgList = smsEntity.toFileStringList();
			if (msgList != null) {
				for (int j = 0; j < msgList.size(); j++) {
					FileWriterTask.queue.offer(new FileRoute(
							FileRoute.KEY_SMS_OLD_SEND, msgList.get(j)));
				}
			}

//			try {
//				AppStaticConfigs.fileManage
//						.getOldSmsWriter().write(smsEntity);
//			} catch (IOException e) {
//				logger.error("writer file error !!");
//			}
		}
				
	}




	private void forbidHandle() {
		RedisScript<List> script = new DefaultRedisScript<List>(
				AppStaticConfigs.luaGetForbid, List.class);

		List<String> keys = new ArrayList<>();
		keys.add(AppStaticConfigs.iSMForbidZSet);
		keys.add(AppStaticConfigs.pSMCacheHash);

		
		List<List<String>> entities = AppStaticConfigs.scriptOpts3
				.getSMCacheAndHash(script, keys,
						0 + "",
						System.currentTimeMillis() + "",
						0 +"",
						AppStaticConfigs.mtfbdBatchSizePerTime+ "",
						AppStaticConfigs.smsSrvId		);


		
		for (int i = 0; i < entities.size(); i++) {
			logger.info("读取到" + entities.size() + "该平台下的禁发时段的短信");
			List<String> list = entities.get(i);
			MtOldSms smsEntity = MtOldSms
					.parse(list);
			// 写入文件中
//			FileWriterTask.queue.offer(new FileRoute(FileRoute.KEY_SMS_OLD_SEND,smsEntity.toFileString()));
			List<String> msgList = smsEntity.toFileStringList();
			if (msgList != null) {
				for (int j = 0; j < msgList.size(); j++) {
					FileWriterTask.queue.offer(new FileRoute(
							FileRoute.KEY_SMS_OLD_SEND, msgList.get(j)));
				}
			}
//			try {
//				AppStaticConfigs.fileManage
//						.getOldSmsWriter().write(smsEntity);
//			} catch (IOException e) {
//				logger.error("writer file error !!");
//			}
			
		}

	}
	



	public boolean isKeepGoing() {
		return keepGoing;
	}

	public void setKeepGoing(boolean keepGoing) {
		this.keepGoing = keepGoing;
	}

	@Override
	public void destroy() {
		logger.info("平台一键切换线程正在退出");
		platformSwitchPool.shutdown();
		this.setKeepGoing(false);
		this.interrupt();
		
	}

}
